package com.yoga.common;

import com.alibaba.fastjson2.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.yoga.utils.JsonResult;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;

/**
 * @author yan
 * @date 2025/8/19
 */
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Value("${jwt.secret}")
    private String secret;
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    public void setRedisTemplate(RedisTemplate<Object, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {

        // 获取jwt
        String jwt = req.getHeader("jwt");
        //检查JWT是否在黑名单
        Boolean isInBlackList = redisTemplate.hasKey("jwt:blacklist:"+jwt);
        if (isInBlackList){
            String msg = "jwt已失效";
            resp.setStatus(HttpStatus.UNAUTHORIZED.value());
            resp.setContentType("application/json;charset=UTF-8");
            PrintWriter out = resp.getWriter();
            out.write(JSON.toJSONString(JsonResult.fail(401,msg)));
            out.flush();
            return false;
        }
        // 验证jwt
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
        //获取解密后的jwt
        try {
            DecodedJWT decodedJWT = verifier.verify(jwt);
            return true;
        } catch (JWTVerificationException e) {
            String msg = "jwt无效或过期";
            resp.setStatus(HttpStatus.UNAUTHORIZED.value());//401
            resp.setContentType("application/json;charset=UTF-8");
            PrintWriter out = resp.getWriter();
            out.write(JSON.toJSONString(JsonResult.fail(401,msg)));
            out.flush();
            return false;
        }
    }
}
